module TableView {
    export enum Direction {
        noChanged = 1,  
        alwaysTop,
        alwaysBottom
    }

    enum RefreshState {
        normal = 1,
        willdownRefresh,
        startdownRefresh,
        downRefreshing,
        willupLoad,
        startupLoad,
        upLoading
    }


    export class TableView extends eui.Scroller {

        private _dataGroup: eui.DataGroup; // 数据源包装
        private _dataSource: any[]; // 数据源
        private _collection: eui.ArrayCollection;
        private _itemRenderer: any;
        private _itemRendererSkinName: any;
        public direction: TableView.Direction = Direction.noChanged; // 刷新数据源时，tableView的位置

        
        private _currentRefreshState:RefreshState = RefreshState.normal;

        private _config:Object; // 单独配置项
        private _tempBottomV = 0;

        private loading = false;

        private scrollDirection = 0; // 滑动方向 正数为上拉 负数为下拉
        private lastPosition = 0; // 记录上次的滚动点 用于判断方向
        public refreshAction:()=>void; // 刷新回调事件 如果存在 则可以下拉刷新
        public loadAction:()=>void; // 加载回调事件 如果存在 则可以上拉加载
        public scrollEndAction:()=>void; // 滚动到最底部就走
        private _isRefreshing: boolean; // 判断是否在下拉刷新中
        private _isUploading: boolean; // 判断是否在上拉加载中

        public _endRefreshing:boolean; // 停止下拉刷新
        public _endLoading:boolean; // 停止上拉加载
        public _headerView:RefreshTopView; // 自定义下拉刷新显示
        public _footerView:RefreshBottomView; // 自定义上拉加载显示

        private _loadEnd:boolean; // 停止加载

        constructor() {
            super();
            // 1.不管数据多少 只要有数据 都可以滚动
            this.scrollPolicyV = eui.ScrollPolicy.ON;

            this.touchEnabled = true;

            // 2. 初始化配置项
            this._config = {
                movieClipJsonName: '', // 菊花帧动画json文件名
                movieClipImgName: '', // 菊花帧动画图片文件名
                movieClipActionName: 'juhua', // 菊花动画名称
                willUpLoadTitle: '',//'上拉加载更多数据...',  // 将要上拉时的标题
                canUploadTitle:'',//'松手加载更多数据!', // 松手加载更多数据
                upLoadingTitle: '',//'加载中...', // 上拉加载过程中的标题
                willDownRefreshTitle: '',//'下拉刷新最新数据', // 将要下拉刷新时的标题
                downRefreshTitle: '',//'刷新中...', // 下拉刷新过程中的标题
                canRefreshTitle: '',//'松手刷新数据!',
                downRegreshedTitle: '',//'刷新完成!', // 下拉刷新完成时的标题
                noMoreDataTitle: '',//'没有更多数据了', // 没有数据了的标题
                topInstance: 40, // 下拉时的界限
                bottomInstance:40 // 上拉时的界限
            }

            // 2.添加到父视图监听
            this.addEventListener(egret.Event.ADDED_TO_STAGE, this.viewDidLoad, this);
        }
        
        private viewDidLoad(event:egret.Event):void {
            // 1. 是否需要监听滚动 以防万一 如果没必要就删除监听
            if(this.refreshAction || this.loadAction){
                if(!this.hasEventListener(egret.Event.CHANGE)){
                    this.addEventListener(egret.Event.CHANGE, this.scrollIsScrolling, this);
                    this.addEventListener(eui.UIEvent.CHANGE_END, this.scrollDidEnd, this);
                }
            }else{
                if(this.hasEventListener(egret.Event.CHANGE)){
                    this.removeEventListener(egret.Event.CHANGE, this.scrollIsScrolling, this);
                }
                if(this.hasEventListener(eui.UIEvent.CHANGE_END)){
                    this.removeEventListener(eui.UIEvent.CHANGE_END, this.scrollDidEnd, this);
                }
            }

        }

        /*********************************************** public **********************************************************/
        public addItem(value: any) {
            this._collection.addItem(value);
        }
        public addItemAt(value: any, index: number) {
            this._collection.addItemAt(value, index);
        }
        public removeItemAt(index: number) {
            this._collection.removeItemAt(index);
        }
        public removeAll() {
            this._collection.removeAll();
        }

        public reset(){
            this._isRefreshing = false;
            this._isUploading = false;
            this.endRefreshing = true;
            this.endLoading = true;
            this._currentRefreshState = RefreshState.normal;
            this.loadEnd = false;
            this.removeFooterView();
            this.removeHeaderView();
        }

        /*********************************************** scroller **********************************************************/
        private scrollIsScrolling(event:egret.Event):void {
            if(this._isUploading || this._isRefreshing){
                return ;    
            }

            // 判断当前滑动的方向 正数为上拉 负数为下拉
            this.scrollDirection = (this.viewport.scrollV - this.lastPosition);
            if (this.scrollDirection == 0) return; // 滚动方向等于0就直接忽略 很讨厌
            this.lastPosition = this.viewport.scrollV;

            if(this.viewport.contentHeight >= this.height){
                this.higherScrollingAction();
            }else{
                this.lowerScrollingAction();
            }

            
        }

        // 滚动监听事件 当内容大于屏幕时
        private higherScrollingAction(){
            // 上拉
            if(this.scrollDirection > 0){
                // 也有可能是下拉的回弹
                if(this.viewport.scrollV < 0){
                    if(!this.refreshAction) return;
                    if(this.viewport.scrollV < -this.config['topInstance']){
                        if(this._currentRefreshState != RefreshState.startdownRefresh){
                            this._currentRefreshState = RefreshState.startdownRefresh;
                            this.startRefreshAction();
                        }
                    }
                }else{
                    // 上拉事件
                    if(!this.loadAction) return;
                    if(this.loadEnd) return;
                    this._tempBottomV = this.viewport.scrollV + this.height - this.viewport.contentHeight;
                    if(this._tempBottomV < 0) return;
                    if(this._tempBottomV < this.config['bottomInstance'])
                    {// 准备上拉加载状态 在上拉 但是还没到达指定位置
                        if(this._currentRefreshState != RefreshState.willupLoad){
                            this._currentRefreshState = RefreshState.willupLoad;
                            // 准备上拉加载时 要干啥？
                            this.willuploadAction();
                        }
                    }else
                    {// 上拉加载状态
                        if(this._currentRefreshState != RefreshState.upLoading){
                            this._currentRefreshState = RefreshState.upLoading;
                            // 上拉加载时 要干啥？
                            this.upLoadingAction();
                        }
                    }
                }
            }else{ // 下拉
                this._tempBottomV = this.viewport.scrollV + this.height - this.viewport.contentHeight;
                 if(this._tempBottomV > 0){// 上拉的回弹
                    if(!this.loadAction) return;
                    if(this.loadEnd) return;
                    if(this._tempBottomV > this.config['bottomInstance']){
                        if(this._currentRefreshState != RefreshState.startupLoad){
                            this._currentRefreshState = RefreshState.startupLoad;
                            this.startUpLoadAction();
                        }
                    }
                }else{
                    // 下拉事件
                    // 如果action不存在 直接啥都不干
                    if(!this.refreshAction) return;
                    // 大于0 说明是正常的滚动 直接忽略
                    if(this.viewport.scrollV > 0) return;
                    // 超出一定范围 触发下拉加载事件
                    if(this.viewport.scrollV < - this.config['topInstance']){
                        // 开始下拉刷新
                        if(this._currentRefreshState != RefreshState.downRefreshing){
                            this._currentRefreshState = RefreshState.downRefreshing;
                            // 下拉刷新时 要干啥？
                            this.refreshingAction();
                        }
                    }else{
                        // 准备下拉刷新 在下拉 但是还没到达指定位置
                         if(this._currentRefreshState != RefreshState.willdownRefresh){
                            this._currentRefreshState = RefreshState.willdownRefresh;
                            // 即将下拉刷新时 要干啥
                            this.willRefreshAction();
                        }                       
                    }

                }
            }
        }

        // 滚动监听事件 当内容小于屏幕时
        private lowerScrollingAction(){
            // 上拉
            if(this.scrollDirection > 0){
                if(this.viewport.scrollV < 0) // 下拉回弹
                {
                     if(!this.refreshAction) return;
                     if(this.viewport.scrollV <= -this.config['topInstance']){
                         if(this._currentRefreshState != RefreshState.startdownRefresh){
                            this._currentRefreshState = RefreshState.startdownRefresh;
                            this.startRefreshAction();
                        }
                     }
                }else{ // 上拉事件
                    if(!this.loadAction) return;
                    if(this.loadEnd) return;
                    if(this.viewport.scrollV < this.config['bottomInstance'])
                    { // 准备上拉加载状态 在上拉 但是还没到指定位置
                        if(this._currentRefreshState != RefreshState.willupLoad){
                            this._currentRefreshState = RefreshState.willupLoad;
                            // 准备上拉加载时 要干啥？
                            this.willuploadAction();
                        }
                    }else 
                    {// 上拉加载状态
                        if(this._currentRefreshState != RefreshState.upLoading){
                            this._currentRefreshState = RefreshState.upLoading;
                            // 上拉加载时 要干啥？
                            this.upLoadingAction();
                        }
                    }
                }
            }
            else
            {// 下拉
                if(this.viewport.scrollV > 0){ // 上拉回弹
                    if(this.loadEnd) return;
                    if(!this.loadAction) return;
                    if(this.viewport.scrollV >= this.config['bottomInstance']){
                        if(this._currentRefreshState != RefreshState.startupLoad){
                            this._currentRefreshState = RefreshState.startupLoad;
                            this.startUpLoadAction();
                        }
                    }
                }else
                { // 下拉事件
                    if(!this.refreshAction) return;
                    if(this.viewport.scrollV < - this.config['topInstance'])
                    { // 下拉刷新状态
                        if(this._currentRefreshState != RefreshState.downRefreshing){
                            this._currentRefreshState = RefreshState.downRefreshing;
                            // 下拉刷新时 要干啥？
                            this.refreshingAction();
                        }
                    }else{
                        //  准备下拉刷新 在下拉 但是还没到达指定位置
                        if(this._currentRefreshState != RefreshState.willdownRefresh){
                            this._currentRefreshState = RefreshState.willdownRefresh;
                            // 即将下拉刷新时 要干啥
                            this.willRefreshAction();
                        }   
                    }
                }
            }
        }

        
        private scrollDidEnd(event:egret.Event){
            // if(this.loadEnd){
            //     console.log(this.loadEnd);
            //     this.addFooterView();
            //     this.footerView.endAnimation();
            //     this.footerView.title = this.config['noMoreDataTitle'];
            //     if(this.scrollEndAction) this.scrollEndAction();
            // }
            if(this._isUploading){
                if(!this.loadAction) return;
                if(this.viewport.contentHeight > this.height){
                    if(this.viewport.scrollV >= (this.viewport.contentHeight - this.height)){
                        if(this.loadEnd){
                            this.footerView.endAnimation();
                            this.footerView.title = this.config['noMoreDataTitle'];
                            if(this.scrollEndAction) this.scrollEndAction();
                        }else{
                            this.footerView.title = this.config['upLoadingTitle'];
                            this.footerView.startAnimation();
                        }
                        var scrollV = this.viewport.contentHeight + this.footerView.height - this.height;
                        egret.Tween.removeTweens(this.viewport);
                        egret.Tween.get(this.viewport).to({'scrollV': scrollV}, 100);
                    }
                }else{ 
                    if(this.loadEnd){
                        this.footerView.endAnimation();
                        this.footerView.title = this.config['noMoreDataTitle'];
                        if(this.scrollEndAction) this.scrollEndAction();
                    }else{
                        this.footerView.title = this.config['upLoadingTitle'];
                        this.footerView.startAnimation();
                    }
                    egret.Tween.removeTweens(this.viewport);
                    egret.Tween.get(this.viewport).to({'scrollV': 0}, 100);
                }
            }

            if(this._isRefreshing && this.viewport.scrollV <= 0){
                if(!this.refreshAction) return;
                this.headerView.title = this.config['downRefreshTitle'];
                this.headerView.startAnimation();
                egret.Tween.removeTweens(this.viewport);
                egret.Tween.get(this.viewport).to({'scrollV': -this.headerView.height}, 100);
            }
        } 


        /*********************************************** private **********************************************************/
        private vcTimeOut;
        private dataChanged(event: eui.CollectionEvent): void {
            switch(this.direction){
                case Direction.alwaysBottom:
                    this.alwaysBottomAction();
                    break;
                case Direction.alwaysTop:
                    this.viewport.scrollV = 0;
                    break;
            }
        }

        private alwaysBottomAction(){
            var self = this;
            if (this.vcTimeOut != null) egret.clearTimeout(this.vcTimeOut);
            // 加一个延时调用 不然获取不到真正的contentHeight
            this.vcTimeOut = egret.setTimeout(function () {
                if (self.viewport.contentHeight > self.height) {
                    self.viewport.scrollV = self.viewport.contentHeight - self.height;
                }
                egret.clearTimeout(self.vcTimeOut);
                self.vcTimeOut = null;
            }, this, 100);
        }

        
        // 即将上拉加载时的操作
        private willuploadAction(){
            // 添加footerView
            this.addFooterView();
            // 改变提示语
            this.footerView.title = this.config['willUpLoadTitle'];
            // 菊花不做动画
            this.footerView.endAnimation();
        }

        // 上拉加载后的回弹 
        private startUpLoadAction(){
            // // 说明此时是上拉回弹
            // var scrollV = this.viewport.contentHeight + this.footerView.height - this.height;
            // egret.Tween.removeTweens(this.viewport);
            // // console.log(scrollV);
            // egret.Tween.get(this.viewport).to({'scrollV': scrollV}, 300).call(function(){
            //     if(this.loadAction) this.loadAction();
            //     this._isUploading = true;
            // }.bind(this));
            // // this.viewport.scrollV = scrollV;
            // console.log('设置scrollV了' + scrollV);
            this._isUploading = true;
            if(this.loadAction) this.loadAction();
        }

        // 松手开始加载时的操作
        private upLoadingAction(){
            // 添加footerView
            this.addFooterView();
            // 改变提示语
            this.footerView.title = this.config['canUploadTitle'];
            // // 菊花开始做动画
            // this.footerView.startAnimation();
        }

        private addFooterView(){
            var group: eui.Group = <eui.Group>this.viewport;
            if (!group.contains(this.footerView)) {
                group.addChild(this.footerView);
            }
            this.footerView.y = this.viewport.contentHeight;
        }

        private removeFooterView(){
            var group: eui.Group = <eui.Group>this.viewport;
            if (group.contains(this.footerView)) {
                group.removeChild(this.footerView);
            }
        }

        // 开始下拉刷新的操作
        private refreshingAction(){
            // 添加headerView
            this.addHeaderView();
            // 改变提示语
            this.headerView.title = this.config['canRefreshTitle'];
            // // 菊花开始做动画
            // this.headerView.startAnimation();
        }

        // 即将下拉刷新的操作
        private willRefreshAction(){
            // 添加headerView
            this.addHeaderView();
            // 改变提示语
            this.headerView.title = this.config['willDownRefreshTitle'];
            // 菊花不做动画
            this.headerView.endAnimation();
        }

        // 下拉刷新的回弹
        private startRefreshAction(){
            this._isRefreshing = true;
            this.loadEnd = false;
            if(this.refreshAction) this.refreshAction();
        }

        private addHeaderView(){
            var group: eui.Group = <eui.Group>this.viewport;
            if (!group.contains(this.headerView)) {
                group.addChild(this.headerView);
            }
            this.headerView.y = - this.headerView.height;
        }

        private removeHeaderView(){
            var group: eui.Group = <eui.Group>this.viewport;
            if (group.contains(this.headerView)) {
                group.removeChild(this.headerView);
            }
        }

        /*********************************************** setter **********************************************************/
        public set dataSource(value: any[]) {
            this._dataSource = value;
            this.collection.source = value
            this.dataGroup.dataProvider = this._collection;

        }
        public set itemRenderer(value: any) {
            this._itemRenderer = value;
            this.dataGroup.itemRenderer = value;
        }
        public set itemRendererSkinName(value: any) {
            this._itemRendererSkinName = value;
            this.dataGroup.itemRendererSkinName = value;
        }
        private set collection(value: eui.ArrayCollection) {
            this._collection = value;
        }
        public set headerView(value: RefreshTopView) {
            this._headerView = value;
        }
        public set footerView(value: RefreshBottomView) {
            this._footerView = value;
        }
        public set endLoading(value: boolean) {
            this._endLoading = value;
            if(value && this._isUploading){
                this._isUploading = false;
                this.removeFooterView();
            }
        }
        
        public set endRefreshing(value: boolean) {
            this._endRefreshing = value;
            if(value && this._isRefreshing){
                this._isRefreshing = false;
                this.removeHeaderView();
                egret.Tween.removeTweens(this.viewport);
                egret.Tween.get(this.viewport).to({'scrollV': 0}, 200);
            }
        }
        public set loadEnd(value: boolean) {
            this._loadEnd = value;
            if(value && this.loadAction && this._currentRefreshState != RefreshState.normal){
                this.footerView.title = this.config['noMoreDataTitle'];
                this.footerView.endAnimation();
            }
        }

        /*********************************************** getter **********************************************************/
        private get dataGroup(): eui.DataGroup {
            if (!this._dataGroup) {
                var dataGroup = new eui.DataGroup();
                dataGroup.percentWidth = 100;
                dataGroup.percentHeight = 100;
                this._dataGroup = dataGroup;
                this.viewport = this._dataGroup;
            }
            return this._dataGroup;
        }
        public get itemRenderer(): any {
            return this._itemRenderer;
        }
        public get itemRendererSkinName(): any {
            return this._itemRendererSkinName;
        }
        private get collection(): eui.ArrayCollection {
            if (!this._collection) {
                this._collection = new eui.ArrayCollection();
                this._collection.addEventListener(eui.CollectionEvent.COLLECTION_CHANGE, this.dataChanged, this);
            }
            return this._collection;
        }
        public get dataSource(): any[] {
            return this._dataSource;
        }
        public get config(): Object {
            return this._config;
        }
        public get footerView(): RefreshBottomView {
            if(!this._footerView){
                var footerView = new RefreshBottomView();
                footerView.width = this.width;
                footerView.height = 40;
                this._footerView = footerView;
            }
            return this._footerView;
        }
        public get headerView(): RefreshTopView {
            if(!this._headerView){
                var headerView = new RefreshTopView();
                headerView.width = this.width;
                headerView.height = 40;
                this._headerView = headerView;
            }
            return this._headerView;
        }
        public get loadEnd(): boolean {
            return this._loadEnd;
        } 
    }

    class RefreshTopView extends egret.DisplayObjectContainer {
        public role: egret.MovieClip// 帧动画
        private _titleLabel: egret.TextField; // 提示语
        private _title:string; // 提示语

        constructor() {
            super();
            this.addEventListener(egret.Event.ADDED_TO_STAGE, this.viewDidLoad, this);
        }

        private viewDidLoad() {
            // this.createRole();
            if (!this.contains(this.titleLabel)) this.addChild(this.titleLabel);
        }

        /*********************************************** public **********************************************************/
        public startAnimation() {
            // if (this.role) {
            //     if (!this.contains(this.role)) {
            //         this.addChild(this.role);
            //     }
            //     if (!this.role.isPlaying) this.role.gotoAndPlay(-1, -1);
            // }
        }

        public endAnimation() {
            // if (!this.role) return;
            // if (this.role.isPlaying) this.role.stop();
            // if (this.contains(this.role)) {
            //     this.removeChild(this.role);
            // }
        }
        /*********************************************** private **********************************************************/
        private createRole() {
            var self = this;
            // var manager = new MovieClipManager();
            // manager.play('juhua', 'juhua', 'juhua', function (role: egret.MovieClip) {
            //     self.role = role;
            //     role.anchorOffsetX = role.width / 2.0;
            //     role.x = self.width / 2.0;
            //     self.titleLabel.y = role.y + role.height;
            // });
        }
        /*********************************************** setter **********************************************************/
        public set titleLabel(value: egret.TextField) {
            this._titleLabel = value;
        }
        
        public set title(value: string) {
            this._title = value;
            this.titleLabel.text = value;
        }
        /*********************************************** getter **********************************************************/
        public get titleLabel(): egret.TextField {
            if (!this._titleLabel) {
                var titleLabel = new egret.TextField();
                titleLabel.textColor = 0x555555; 
                titleLabel.size = 25;
                titleLabel.width = this.width;
                titleLabel.textAlign = egret.HorizontalAlign.CENTER;
                this._titleLabel = titleLabel;
            } 
            return this._titleLabel;
        }
    }

    class RefreshBottomView extends egret.DisplayObjectContainer {
        public role: egret.MovieClip// 帧动画
        private _titleLabel: egret.TextField; // 提示语展示
        private _title:string; // 提示语

        constructor() {
            super();
            this.addEventListener(egret.Event.ADDED_TO_STAGE, this.viewDidLoad, this);
        }

        private viewDidLoad() {
            // this.createRole();
            if(!this.contains(this.titleLabel)) this.addChild(this.titleLabel);
        }


        /*********************************************** public **********************************************************/
        public startAnimation() {
            // if (this.role) {
            //     if (!this.contains(this.role)) {
            //         this.addChild(this.role);
            //     }
            //     this.role.gotoAndPlay(-1, -1);
            // }
        }

        public endAnimation() {
            // if (!this.role) return;
            // if (this.role.isPlaying) this.role.stop();
            // if (this.contains(this.role)) {
            //     this.removeChild(this.role);
            // }
        }

        /*********************************************** private **********************************************************/
        private createRole() {
            var self = this;
            // var manager = new MovieClipManager();
            // manager.play('juhua', 'juhua', 'juhua', function (role: egret.MovieClip) {
            //     self.role = role;
            //     self.role.anchorOffsetX = self.role.width / 2.0;
            //     role.x = self.width / 2.0;
            //     role.y = self.titleLabel.y + self.titleLabel.height;
            // });
        }

        /*********************************************** setter **********************************************************/
        public set titleLabel(value: egret.TextField) {
            this._titleLabel = value;
        }

        
        public set title(value: string) {
            this._title = value;
            this.titleLabel.text = value;
        }

        /*********************************************** getter **********************************************************/
        public get titleLabel(): egret.TextField {
            if (!this._titleLabel) {
                var titleLabel = new egret.TextField();
                titleLabel.textColor = 0x555555;
                titleLabel.size = 25;
                titleLabel.textAlign = egret.HorizontalAlign.CENTER;
                titleLabel.width = this.width;
                titleLabel.y = 5;
                this._titleLabel = titleLabel;
            }
            return this._titleLabel;
        }
    }


}



